#include "mainwindow.h"
#include <QPainter>
#include <QDebug>
#include <QProcess>
#include <QFile>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , m_scene(new QGraphicsScene(this))
    , m_videoView(new QGraphicsView())
    , m_pixmapItem(new QGraphicsPixmapItem())
    , m_gstPipeline(nullptr)
    , m_frameCount(0)
    , m_lastFpsUpdate(0)
{
    setupUI();
    
    // 先创建GStreamerPipeline对象
    m_gstPipeline = new GStreamerPipeline(this);
    
    setupConnections();
}

MainWindow::~MainWindow()
{
    if (m_gstPipeline) {
        m_gstPipeline->stopPipeline();
    }
}

void MainWindow::setupUI()
{
    setWindowTitle("摄像头采集系统 - Mail-G610 GPU (高性能模式)");
    setMinimumSize(1000, 700);
    
    // 中央窗口
    QWidget *centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);
    
    // 主布局
    QHBoxLayout *mainLayout = new QHBoxLayout(centralWidget);
    
    QWidget *videoContainer = new QWidget;
    QVBoxLayout *videoLayout = new QVBoxLayout(videoContainer);

    // 配置视频视图
    m_videoView->setScene(m_scene);
    m_videoView->setRenderHint(QPainter::Antialiasing, false);
    m_videoView->setOptimizationFlags(QGraphicsView::DontSavePainterState);
    m_videoView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
    m_videoView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_videoView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    m_scene->addItem(m_pixmapItem);
    
    videoLayout->addWidget(m_videoView);
    
    // 控制面板
    QWidget *controlPanel = new QWidget;
    controlPanel->setMaximumWidth(300);
    controlPanel->setMinimumWidth(250);
    
    QVBoxLayout *controlLayout = new QVBoxLayout(controlPanel);
    
    // 系统控制组
    QGroupBox *systemGroup = new QGroupBox("系统控制");
    QFormLayout *systemLayout = new QFormLayout(systemGroup);
    
    m_btnStartStop = new QPushButton("开启");
    m_btnRecord    = new QPushButton("开始录制");
    m_btnStream    = new QPushButton("开始推流");
    m_cbResolution = new QComboBox;
    
    // 自动检测可用分辨率
    detectAvailableResolutions();
    
    systemLayout->addRow("摄像头:", m_btnStartStop);
    systemLayout->addRow("录制控制:", m_btnRecord);
    systemLayout->addRow("推流控制:", m_btnStream);
    systemLayout->addRow("分辨率:", m_cbResolution);
    
    // 性能信息组
    QGroupBox *perfGroup = new QGroupBox("性能信息");
    QFormLayout *perfLayout = new QFormLayout(perfGroup);
    
    m_lblFPS = new QLabel("0");
    m_lblStatus = new QLabel("就绪");
    m_lblRecordStatus = new QLabel("未录制");
    m_lblStreamStatus = new QLabel("未推流");
    m_lblGPUStatus = new QLabel("GPU: 0%");
    


    perfLayout->addRow("FPS:", m_lblFPS);
    perfLayout->addRow("摄像头状态:", m_lblStatus);
    perfLayout->addRow("录制:", m_lblRecordStatus);
    perfLayout->addRow("推流:", m_lblStreamStatus);
    perfLayout->addRow("GPU使用率:", m_lblGPUStatus);

    // 信息显示组
    QGroupBox *infoGroup = new QGroupBox("系统信息");
    QVBoxLayout *infoLayout = new QVBoxLayout(infoGroup);
    
    QLabel *infoLabel = new QLabel(
        "摄像头采集系统\n\n"
        "格式: MJPEG\n"
        "后端: GStreamer\n"
        "GPU: Mail-G610\n"
        "框架: QT5\n"
        "模式: 三合一\n\n"
        "功能:\n"
        "• 实时预览\n"
        "• MP4录制\n"
        "• RTMP推流"
    );

    infoLabel->setWordWrap(true);
    infoLabel->setAlignment(Qt::AlignTop);
    
    infoLayout->addWidget(infoLabel);
    
    // 组装控制面板
    controlLayout->addWidget(systemGroup);
    controlLayout->addWidget(perfGroup);
    controlLayout->addWidget(infoGroup);
    controlLayout->addStretch();
    
    // 组装主布局
    mainLayout->addWidget(videoContainer, 1);
    mainLayout->addWidget(controlPanel);
    
    // 性能计时器
    m_performanceTimer = new QTimer(this);
    m_performanceTimer->start(1000); // 每秒更新
    m_lastFpsUpdate = QDateTime::currentMSecsSinceEpoch();
}



void MainWindow::setupConnections()
{
    // 先连接按钮和定时器的信号
    // 开启/关闭摄像头
    connect(m_btnStartStop, &QPushButton::clicked, this, &MainWindow::onStartStopClicked);
    // 开启/关闭录制
    connect(m_btnRecord, &QPushButton::clicked, this, &MainWindow::onRecordClicked);
    // 开启/关闭推流
    connect(m_btnStream, &QPushButton::clicked, this, &MainWindow::onStreamClicked);
    // 选择分辨率
    connect(m_cbResolution, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MainWindow::onResolutionChanged);
    // 更新信息
    connect(m_performanceTimer, &QTimer::timeout, this, &MainWindow::updatePerformanceInfo);
    
    // 确保GStreamerPipeline对象已经创建后再连接信号
    if (m_gstPipeline) {
        
        // 使用高性能模式
        connect(m_gstPipeline, &GStreamerPipeline::newFrameDataAvailable, 
                this, &MainWindow::onNewFrameDataReceived, Qt::QueuedConnection);
        
    }
}

// 高性能模式槽函数
void MainWindow::onNewFrameDataReceived(const FrameData &frameData)
{
    m_frameCount++;
    
    if (frameData.isValid()) {
        // 直接使用指针创建QImage（零拷贝）
        QImage image(frameData.data, frameData.width, frameData.height, frameData.format);
        
        // 显示图像
        QPixmap pixmap = QPixmap::fromImage(image);
        m_pixmapItem->setPixmap(pixmap);
        m_scene->setSceneRect(pixmap.rect());
        
        // 调用清理函数释放GStreamer资源
        if (frameData.cleanup) {
            frameData.cleanup();
        }
    }
}



void MainWindow::onStartStopClicked()
{
    if (!m_gstPipeline) {
        m_lblStatus->setText("错误: 管道未初始化");
        return;
    }
    
    if (m_gstPipeline->isRunning()) {
        m_gstPipeline->stopPipeline();
        m_btnStartStop->setText("开启");
        m_lblStatus->setText("已停止");
    } else {
        // 解析分辨率
        QString resolution = m_cbResolution->currentText();
        QStringList dims = resolution.split('x');
        if (dims.size() == 2) {
            int width = dims[0].toInt();
            int height = dims[1].toInt();
            
            m_lblStatus->setText("初始化中...");
            QApplication::processEvents(); // 更新UI
            
            if (m_gstPipeline->initializePipeline("/dev/video0", width, height, 30)) {
                if (m_gstPipeline->startPipeline()) {
                    m_btnStartStop->setText("停止");
                    m_lblStatus->setText(QString("运行中"));
                } else {
                    m_lblStatus->setText("启动失败");
                    QMessageBox::critical(this, "错误", "无法启动视频管道");
                }
            } else {
                m_lblStatus->setText("初始化失败");
                QMessageBox::critical(this, "错误", "无法初始化视频管道");
            }
        }
    }
}

void MainWindow::onResolutionChanged(int index)
{
    Q_UNUSED(index)
    // 分辨率改变时需要重启管道
    if (m_gstPipeline && m_gstPipeline->isRunning()) {
        onStartStopClicked(); // 停止
        QTimer::singleShot(100, this, [this]() { onStartStopClicked(); }); // 重新开始
    }
}

void MainWindow::updatePerformanceInfo()
{
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    qint64 elapsed = currentTime - m_lastFpsUpdate;
    
    if (elapsed > 0) {
        double fps = (m_frameCount * 1000.0) / elapsed;
        m_lblFPS->setText(QString::number(fps, 'f', 1));
    }
    
    // 读取 GPU 使用率（如果可用）
    QFile gpuFile("/sys/class/devfreq/fb000000.gpu/load");
    if (gpuFile.exists() && gpuFile.open(QIODevice::ReadOnly)) {
        QByteArray gpuLoad = gpuFile.readAll().trimmed();
        m_lblGPUStatus->setText(QString("GPU: %1%").arg(QString(gpuLoad)));
        gpuFile.close();
    }

    m_frameCount = 0;
    m_lastFpsUpdate = currentTime;
}

// 查询v4l2摄像头分辨率
void MainWindow::detectAvailableResolutions()
{
    m_cbResolution->clear();
    m_availableResolutions.clear();
    
    qDebug() << "开始检测摄像头可用分辨率...";
    
    // 方法1: 使用v4l2-ctl命令检测
    QProcess process;
    process.start("v4l2-ctl", {"--list-formats-ext", "-d", "/dev/video0"});
    
    if (process.waitForFinished(3000)) {
        QString output = process.readAllStandardOutput();
        QStringList lines = output.split('\n');
        
        QRegularExpression resRegex(R"((\d+)x(\d+))");
        
        for (const QString &line : lines) {
            QRegularExpressionMatch match = resRegex.match(line);
            if (match.hasMatch()) {
                int width = match.captured(1).toInt();
                int height = match.captured(2).toInt();
                addResolution(width, height);
            }
        }
    } 
    
    // 按分辨率大小排序（从大到小）
    std::sort(m_availableResolutions.begin(), m_availableResolutions.end(),
              [](const QPair<int, int> &a, const QPair<int, int> &b) {
                  return (a.first * a.second) > (b.first * b.second);
              });
    
    // 添加到下拉框
    for (const auto &res : m_availableResolutions) {
        m_cbResolution->addItem(QString("%1x%2").arg(res.first).arg(res.second));
    }
    
    // 默认选择中间分辨率
    int defaultIndex = qMin(2, m_cbResolution->count() - 1);
    if (m_cbResolution->count() > 0) {
        m_cbResolution->setCurrentIndex(defaultIndex);
    }
    
    qDebug() << "检测到" << m_availableResolutions.size() << "个可用分辨率";
}

void MainWindow::addResolution(int width, int height)
{
    // 避免重复添加
    for (const auto &res : m_availableResolutions) {
        if (res.first == width && res.second == height) {
            return;
        }
    }
    
    // 只添加常见比例的分辨率
    if ((width == 320 && height == 240) ||   // 4:3
        (width == 640 && height == 480) ||   // 4:3
        (width == 800 && height == 600) ||   // 4:3
        (width == 1024 && height == 768) ||  // 4:3
        (width == 1280 && height == 720) ||  // 16:9
        (width == 1280 && height == 960) ||  // 4:3
        (width == 1920 && height == 1080) || // 16:9
        (width == 1600 && height == 1200) || // 4:3
        (width == 2592 && height == 1944) || // 4:3
        (width >= 320 && width <= 3840 && height >= 240 && height <= 2160)) {
        
        m_availableResolutions.append(qMakePair(width, height));
        qDebug() << "添加分辨率:" << width << "x" << height;
    }
}

/************************************录制******************************************/


void MainWindow::onRecordClicked() {
    if (!m_gstPipeline || !m_gstPipeline->isRunning()){
        QMessageBox::warning(this, "警告", "请先启动摄像头");
        return;
    }

    if (m_gstPipeline->isRecording()) {
        // 停止录制
        if (m_gstPipeline->stopRecording()) {
            m_btnRecord->setText("开始录制");
            m_lblRecordStatus->setText("未录制");
        }
    } else {
        // 开始录制
        QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");
        QString recordPath = QString("/home/orangepi/save_video/video_%1.mp4").arg(timestamp);
        
        if (m_gstPipeline->startRecording(recordPath)) {
            m_btnRecord->setText("停止录制");
            m_lblRecordStatus->setText("录制中...");
        } else {
            QMessageBox::critical(this, "错误", "开始录制失败");
        }
    }
}
/************************************录制******************************************/



/************************************推流******************************************/


void MainWindow::onStreamClicked()
{
    if (!m_gstPipeline || !m_gstPipeline->isRunning()) {
        QMessageBox::warning(this, "警告", "请先启动预览模式");
        return;
    }
    
    if (m_gstPipeline->isStreaming()) {
        // 停止推流
        m_gstPipeline->stopStreaming();
        m_btnStream->setText("开始推流");
        m_lblStreamStatus->setText("未推流");
    } else {
        // 开始推流
        QString streamUrl = "udp://127.0.0.1:1234";
        if (m_gstPipeline->startStreaming(streamUrl)) {
            m_btnStream->setText("停止推流");
            m_lblStreamStatus->setText("推流中");
        }
        
    }

}
/************************************推流******************************************/
